function RV = VotingMatchingPCA_xiaoliw(varargin)
%% Parameters
%close all;
%clear;
%clc;
%PATH = [pwd '\example\'];
%IM_EXTENSION = 'png';

% meanshift parameters:
cSPATIAL_BANDWIDTH =7;
cRANGE_BANDWIDTH = 6.5;
cMIN_REGION_AREA = 30;
cSPEEDUP = 2;
cGRADIENT_WINDOW_RADIOUS = 2;
cMIXTURE_PARAMETER = .3;
cEDGE_SGTRENGTH = .3;


WEIGHT = 1;
% calculate voters information
NUMBER_OF_VOTERS = 1; %4
NUMBER_OF_CANDIDATES = 1;%6
RIGHT_CANDIDATE = 3;
REG_THRES = cMIN_REGION_AREA -5;
votersSigs = {};
votersWeights = {};
votersFeatures = {};
votersLabels = {};
votersRegSizes = {};

% get voters infromation
allFeatures = [];
votersImage = [];
for indexV=1:NUMBER_OF_VOTERS
    %imPath = [PATH sprintf([ 'v%d.' IM_EXTENSION],indexV)];
    %im = imread(imPath);
    %im = imread('test_xiaoliw/foreground (2).tif');
    im = varargin{1};
    im = prepareImage(im);
    
    [fimage,labels,modes,regSize,grad,conf] = edison_wrapper(im, @GetFeatures,'SpatialBandWidth',cSPATIAL_BANDWIDTH,'RangeBandWidth',cRANGE_BANDWIDTH,'MinimumRegionArea',cMIN_REGION_AREA,'SpeedUp',cSPEEDUP,'GradientWindowRadius',cGRADIENT_WINDOW_RADIOUS,'MixtureParameter',cMIXTURE_PARAMETER,'EdgeStrengthThreshold',cEDGE_SGTRENGTH);
    %imagesc(labels);
    f=GetFeatures(im);

    % execulde zero h,s segments (background) and very small regions
    [labels,regSize] =refineSegments(f,labels,regSize,REG_THRES);

    % weights of image 1
    w = regSize;
    %w = w./max(w);

    % signiture means of image 1
    S =getReigionFeatures(f,labels,regSize);
      
    % uncomment to use HOG instead of SIFT and comment the above line 
    allFeatures = getReigionFeaturesPCAHOG(im,labels,regSize,S,allFeatures,REG_THRES);
    
    % collect features from all regions together - SIFT
    % allFeatures = getReigionFeaturesPCA(im,labels,regSize,S,allFeatures,REG_THRES);
    
    cents  = GetCentriods(im,labels,regSize);
    
    votersSigs{indexV} = S;
    votersWeights{indexV} = w;
    votersFeatures{indexV} = f;
    votersLabels{indexV} = labels;
    votersRegSizes{indexV} = regSize;
    votersCents{indexV} = cents;
    
    if indexV==1
        votersImage = im;
    else
        votersImage = appendimages(votersImage,im);
    end;
        
end;


candsSigs = {};
candsWeights = {};
candsRegSizes = {};
for indexC=1:NUMBER_OF_CANDIDATES
    %imPath = [PATH sprintf([ 'c%d.' IM_EXTENSION],indexC)];
    %im = imread(imPath);
    %im = imread('test_xiaoliw/foreground_70.tif');
    %im = imread('test_xiaoliw/foreground (9).tif');
    im = varargin{2};
    im = prepareImage(im);
    [fimage,labels,modes,regSize,grad,conf] = edison_wrapper(im, @GetFeatures,'SpatialBandWidth',cSPATIAL_BANDWIDTH,'RangeBandWidth',cRANGE_BANDWIDTH,'MinimumRegionArea',cMIN_REGION_AREA,'SpeedUp',cSPEEDUP,'GradientWindowRadius',cGRADIENT_WINDOW_RADIOUS,'MixtureParameter',cMIXTURE_PARAMETER,'EdgeStrengthThreshold',cEDGE_SGTRENGTH);


    f=GetFeatures(im);

    % exclude first segment (background) and
    % execulde zero h,s segments
    [labels,regSize] =refineSegments(f,labels,regSize,REG_THRES);

    % weights of image 1
    w = regSize;
    %w = w./max(w);

    % signiture means of image 1
    S =getReigionFeatures(f,labels,regSize);
     
    % uncomment to use HOG instead of SIFT and comment the line above 
    allFeatures = getReigionFeaturesPCAHOG(im,labels,regSize,S,allFeatures,REG_THRES);
   
     % collect features from all regions together - SIFT version
    %allFeatures =
    %getReigionFeaturesPCA(im,labels,regSize,S,allFeatures,REG_THRES);
    
    cents  = GetCentriods(im,labels,regSize);
    
    candsSigs{indexC} = S;
    candsWeights{indexC} = w;
    candsRegSizes{indexC} = regSize;
    candsCents{indexC} = cents;
end;

%% compute new feature space
% sift features
% prepare image for sift

% % Apply PCA
FEATURE_SIZE = 30;
% [COEFF,SCORE,LATENT] = PRINCOMP(allFeatures);
[COEFF,SCORE,LATENT] = princomp(allFeatures);
newFeatures = SCORE(:,1:FEATURE_SIZE);


% return features to voters and candidates 
pointer = 1;
for indexV=1:size(votersSigs,2)
    S = votersSigs{indexV};
    for indexR=1:size(S,2)
        S{indexR} = newFeatures(pointer,:);
        pointer = pointer+1;
    end;
    votersSigs{indexV} = S;
end;
for indexC=1:size(candsSigs,2)
    S = candsSigs{indexC};
    for indexR=1:size(S,2)
        S{indexR} = newFeatures(pointer,:);
        pointer = pointer+1;
    end;
    candsSigs{indexC} = S;
end;

%% apply page rank
% -------------------------------------------------------------------------
%weights before
% Show Voters
%figure(1);clf;
%imshow(votersImage);
%ShowWeights(2,votersWeights,votersLabels);

%recompute weights using all voters segments sizes
votersWeights=rescaleWeights(votersWeights);

%apply page rank
votersWeights=calculateWeightsPCA(votersSigs,votersWeights,votersCents);

%weights after
%ShowWeights(3,votersWeights,votersLabels);
% -------------------------------------------------------------------------


result = [];
for indexC=1:NUMBER_OF_CANDIDATES
    
    w1 = candsWeights{indexC};
    w1  =w1./max(w1);
    w1 = 10.*w1;
    S1 = candsSigs{indexC};
    cent1 = candsCents{indexC};
    
    for index2=1:NUMBER_OF_VOTERS
        S2 = votersSigs{index2};
        w2 = votersWeights{index2};
        w2 = w2./max(w2);
        cent2 = votersCents{index2};
        
        G = GetGroundDistancesPCA(S1,S2,cent1,cent2);
        [e,Flow]=emd_mex(w1,w2,G);
        result(indexC,index2) = e;
    end;
end;

% normalize results by the voters weights
% result = result ./ max(max(result));

if (WEIGHT)
    weightsSum = 0;
    voterPerc = 0;
    for index=1:NUMBER_OF_VOTERS
        weightsSum = weightsSum + sum(votersWeights{index});
    end;

    for index=1:NUMBER_OF_VOTERS
        voterPerc  = sum(votersWeights{index})  ./ weightsSum;
        result(:,index) = exp(-result(:,index)) .* voterPerc;
    end;
end;

result = sum(result,2);
RV = result;
end
%result = result./sum(result)
